﻿using System;
using System.Collections.Generic;
using System.Text;

namespace IFramework
{
    /// 程序集相关的实用函数。
    public class Assembly
    {
        private static readonly System.Reflection.Assembly[] Assemblies = null;
        private static readonly Dictionary<string, Type> CachedTypes = new Dictionary<string, Type>();
        static Assembly()
        {
            Assemblies = AppDomain.CurrentDomain.GetAssemblies();
        }
        /// 获取已加载的程序集。
        public static System.Reflection.Assembly[] GetAssemblies()
        {
            return Assemblies;
        }
        /// 获取已加载的程序集中的所有类型。
        public static Type[] GetTypes()
        {
            List<Type> results = new List<Type>();
            foreach (System.Reflection.Assembly assembly in Assemblies)
            {
                results.AddRange(assembly.GetTypes());
            }
            return results.ToArray();
        }
        /// 获取已加载的程序集中的所有类型。
        public static void GetTypes(List<Type> results)
        {
            if (results == null)
            {
                throw new Exception("Results is invalid.");
            }
            results.Clear();
            foreach (System.Reflection.Assembly assembly in Assemblies)
            {
                results.AddRange(assembly.GetTypes());
            }
        }
        /// 获取已加载的程序集中的指定类型。
        public static Type GetType(string typeName)
        {
            if (string.IsNullOrEmpty(typeName))
            {
                throw new Exception("Type name is invalid.");
            }
            Type type = null;
            if (CachedTypes.TryGetValue(typeName, out type))
            {
                return type;
            }
            type = Type.GetType(typeName);
            if (type != null)
            {
                CachedTypes.Add(typeName, type);
                return type;
            }
            foreach (System.Reflection.Assembly assembly in Assemblies)
            {
                StringBuilder s_CachedStringBuilder = new StringBuilder(1024);
                s_CachedStringBuilder.Length = 0;
                s_CachedStringBuilder.AppendFormat("{0}, {1}", typeName, assembly.FullName);
                type = Type.GetType(s_CachedStringBuilder.ToString());
                if (type != null)
                {
                    CachedTypes.Add(typeName, type);
                    return type;
                }
            }
            return null;
        }
    }
}
